﻿namespace Contoso.Math.MathLibrary
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml;

    /// <summary>
    /// Class for generating the Fibonacci sequence.
    /// </summary>
    public static class Fibonacci
    {
        /// <summary>
        /// Generates the Fibonacci sequence.
        /// </summary>
        /// <param name="length">Number of Fibonacci numbers to generate.</param>
        /// <returns>The Fibonacci sequence.</returns>
        public static long[] GenerateSequence(int length)
        {
            long[] f;

            if (length < 1)
            {
                throw new ArgumentOutOfRangeException("Must be greater than 0", "length");
            }

            if (length > 93)
            {
                throw new ArgumentOutOfRangeException("Must be less than 93", "length");
            }

            if (length == 1)
            {
                return new long[] { 1 };
            }
            else if (length == 2)
            {
                return new long[] { 1, 1 };
            }
            else
            {
                f = new long[length];
                f[0] = 1;
                f[1] = 1;

                for (int i = 2; i < length; i++)
                {
                    f[i] = f[i - 1] + f[i - 2];
                }

                return f;
            }
        }

        public static XmlDocument GenerateResponseMessage(string uow, int length)
        {
            string ns;
            XmlDocument doc;
            XmlElement root;
            XmlElement uowElement;
            XmlElement seqElement;
            XmlElement vElement;
            long[] f;

            ns = "http://contoso.com/biztalkdemo/generatefibonacciresponse/v1";
            f = GenerateSequence(length);

            doc = new XmlDocument();
            root = doc.CreateElement("GenerateFibonacciResponse", ns);
            doc.AppendChild(root);

            uowElement = doc.CreateElement("UnitOfWorkID", ns);
            uowElement.AppendChild(doc.CreateTextNode(uow));

            root.AppendChild(uowElement);

            seqElement = doc.CreateElement("FibonacciSequence", ns);

            for (int i = 0; i < length; i++)
            {
                vElement = doc.CreateElement("V", ns);
                vElement.AppendChild(doc.CreateTextNode(f[i].ToString()));
                seqElement.AppendChild(vElement);
            }

            root.AppendChild(seqElement);

            return doc;
        }
    }
}
